/**
 * @file usermenu_update_image.h
 * @author your name (you@domain.com)
 * @brief 
 * @version 0.1
 * @date 2022-09-27
 * 
 * @copyright Copyright (c) 2022
 * 
 */

#ifndef __USERMENU_UPDATE_IMAGE_H__
#define __USERMENU_UPDATE_IMAGE_H__

#include <dm/lists.h>

#define DEFAULT_FDT_LOAD_ADDR   0x83000000
#define DEFAULT_SYS_LOAD_ADDR	CONFIG_SYS_LOAD_ADDR

#define DEFAULT_BOOT_FILENAME			"u-boot.imx"
#define DEFAULT_FDT_FILENAME			"imx6ull-alpha-14x14-emmc.dtb"
#define DEFAULT_KERNEL_FILENAME			"zImage"
#define DEFAULT_ROOTFS_EXT2_FILENAME	"rootfs.ext2"
#define DEFAULT_ROOTFS_EXT4_FILENAME	"rootfs.ext4"
#define DEFAULT_ALL_FILENAME			"sdcard.img"

#define SD_PARTTION_BOOT0			0
#define EMMC_PARTTION_BOOT0			1
#define MMC_PARTTION_KERNEL			1
#define MMC_PARTTION_ROOTFS			2

typedef enum BLK_DEV_TYPE_E
{
	BLK_DEV_MEMORY = 0,
	BLK_DEV_SD,
	BLK_DEV_EMMC,
	BLK_DEV_NOR_FLASH,
	BLK_DEV_NAND_FLASH,
	BLK_DEV_SSD,
    BLK_DEV_UNKNOWN,
} BLK_DEV_TYPE_ET;

/** 镜像类型 */
typedef enum UPDATE_IMAGE_TYPE_E
{
	IMAGE_IS_UBOOT = 0,	///< u-boot image
	IMAGE_IS_DTB,		///< 设备树
	IMAGE_IS_KERNEL,	///< 内核
	IMAGE_IS_ROOTFS,	///< 文件系统
	IMAGE_IS_ALL,		///< 整体打包的镜像
	IMAGE_IS_UNKOWN,
} UPDATE_IMAGE_TYPE_ET;

typedef struct MMC_BLK_INFO_S
{
	int mmc_dev_num; ///< 设备号
	char *mmc_name;	 ///< 设备名

	int is_boot_dev; ///< 是否是启动设备

	/** bootloader 分区 */
	int default_bootloader;
	int bootloader_part_num0;	///< 需要注意的是 eMMC 的 bootloader 分区有两个，分别为 0 和 1, 这里与 SD 卡不同
	int bootloader_part_num1;
	int bootloader_sector_start;
	int bootloader_sector_offset;

	/** boot 分区存放 linux 镜像和设备树 */
	int boot_part_num;
	int boot_sector_start;

	/** 文件系统 */
	int rootfs_part_num;
	int rootfs_sector_start;
} MMC_BLK_INFO_ST;

typedef struct UPDATE_INFO_S
{
    ulong load_addr;    ///< 镜像的下载地址
    ulong fdt_addr;	    ///< fdt 的下载地址
	/** 以下是各镜像的名称 */
	char uboot[256];
	char kernel[256];
	char dtb[256];
	char rootfs[256];
	char image[256];

	BLK_DEV_TYPE_ET 		boot_dev; ///< 启动设备的类型
	MMC_BLK_INFO_ST			sd_blk_info; ///< sd 卡设备分区信息
	MMC_BLK_INFO_ST 		eMMC_blk_info; ///< eMMC 设备分区信息

	BLK_DEV_TYPE_ET 		update_dev_type; ///< 要更新的设备
	UPDATE_IMAGE_TYPE_ET	update_image; ///< 要更新的镜像
	int 					update_image_size;	///< 升级文件的大小

	//int 					mmc_dev_num;	///< 设备号
	//int 					update_part;	///< 要升级的分区, -1 表示对全镜像升级
} UPDATE_INFO_ST;


int update_image_init(void);
int usermenu_update_image_proc(BLK_DEV_TYPE_ET update_dev_type, UPDATE_IMAGE_TYPE_ET image_type);
#endif